/*
 * UrlFragment.java
 * business
 *
 * Created by ChenTao on 2016/9/21.
 *
 * Copyright (c) 2016年 yidiandao. All rights reserved.
 */

package com.yidiandao.business.ui.url;

import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.BridgeWebViewClient;
import com.yidiandao.business.R;
import com.yidiandao.business.base.BaseEventFragment;
import com.yidiandao.business.constant.Common;
import com.yidiandao.business.data.bean.ShareEntity;
import com.yidiandao.business.data.event.RefreshEnrollResultStateEvent;
import com.yidiandao.business.data.recyclertype.Article;
import com.yidiandao.business.ui.assetabout.coupon.CouponActivity;
import com.yidiandao.business.ui.assetabout.redpacket.RedPacketActivity;
import com.yidiandao.business.ui.brandabout.brandgoods.BrandGoodsActivity;
import com.yidiandao.business.ui.goodsdetail.GoodsDetailActivity;
import com.yidiandao.business.ui.loginabout.login.LoginActivity;
import com.yidiandao.business.ui.loginabout.register.RegisterFragment;
import com.yidiandao.business.ui.main.MainActivity;
import com.yidiandao.business.ui.main.discovery.comment.ArticleCommentActivity;
import com.yidiandao.business.ui.main.discovery.enroll.EnrollActivity;
import com.yidiandao.business.ui.main.discovery.enrollpayfailed.EnrollPayFailedActivity;
import com.yidiandao.business.ui.main.shoppingcart.ShoppingCartFragment;
import com.yidiandao.business.ui.main.shoppingcart.confirmorder.ConfirmOrderActivity;
import com.yidiandao.business.ui.main.shoppingcart.orderresult.OrderResultActivity;
import com.yidiandao.business.ui.shopdetail.ShopDetailActivity;
import com.yidiandao.business.ui.signhistory.SignHistoryActivity;
import com.yidiandao.business.ui.widget.dialog.ShareDialog;
import com.yidiandao.business.ui.widget.view.ArticleOperatorLayout;
import com.yidiandao.business.utils.BuglyUtils;
import com.yidiandao.business.utils.LogUtils;
import com.yidiandao.business.utils.NetworkUtils;
import com.yidiandao.business.utils.StringUtils;
import com.yidiandao.business.utils.UIUtils;
import com.yidiandao.business.utils.UmengUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.List;

import cn.sharesdk.framework.Platform;

import static android.app.Activity.RESULT_OK;
import static com.yidiandao.business.ui.widget.view.ArticleOperatorLayout.POSITION.COMMENT_NOW;

/**
 * 项目中WebView 页面
 */
public class UrlFragment extends BaseEventFragment implements UrlContract.View {

    private static final String TAG = RegisterFragment.class.getSimpleName();

    private static final int FILE_CHOOSER_RESULT_CODE = 10000;

    private UrlContract.Presenter mPresenter;

    private ProgressBar mPbProgress;

    private BridgeWebView mWebView;

    private TextView mTvTitle;

    private Toolbar mToolbar;

    private ArticleOperatorLayout mArticleOperatorLayout;

    private ValueCallback<Uri> uploadMessage;

    private ValueCallback<Uri[]> uploadMessageAboveL;

    private ImageButton mIbtnShare;

    private RelativeLayout mRootContainer;

    private List<String> mImageUrlsFromHtml;

    private LinearLayout mWebViewContainer;

    public static UrlFragment getInstance() {
        UrlFragment fragment = new UrlFragment();
        return fragment;
    }

    @Override
    protected void initViews() {
        mWebViewContainer = (LinearLayout) mRootView.findViewById(R.id.container_web_view);
        mPbProgress = (ProgressBar) mRootView.findViewById(R.id.pb_explainText);
        mTvTitle = (TextView) mRootView.findViewById(R.id.tv_title);
        mToolbar = (Toolbar) mRootView.findViewById(R.id.toolbar);
        mIbtnShare = (ImageButton) mRootView.findViewById(R.id.ibtn_share);
        mRootContainer = (RelativeLayout) mRootView.findViewById(R.id.root_container);

        addWebView();

        // 底部文章 操作栏
        mArticleOperatorLayout = (ArticleOperatorLayout) mRootView.findViewById(R.id.bottom_operator_layout);

        checkIsArticle();
        mPresenter.start();
        initWebViewSettings();
        initListeners();
        mPresenter.registerJavaInterfaceForJs();
    }

    private void addWebView() {
        mWebView = new BridgeWebView(mActivity);

        ViewGroup.LayoutParams params =
                new ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
        mWebView.setLayoutParams(params);
        mWebViewContainer.addView(mWebView);
    }

    private void checkIsArticle() {
        // 检查是否是文章,如果是文章,则需要获取文章的数据信息
        if (mPresenter.checkIsArticle()) {
            // 是文章,隐藏Toolbar,同时显示文章操作Layout
            mPresenter.getArticleInfoFromServer();
        } else {
            // 不是文章,显示Toolbar,同时隐藏文章操作Layout
            setToolbarVisible(true);
            loadUrl();
        }
    }

    @Override
    public void loadUrl() {
        if (NetworkUtils.isNetworkAvailable(mActivity)) {
            mWebView.loadUrl(mPresenter.getUrl());
        } else {
            showToast(UIUtils.getString(R.string.net_no_connect));
        }
    }

    @Override
    public void toUrlActivity(String url) {
        UrlActivity.actionStart(mActivity, url);
    }

    @Override
    public void toCouponActivity() {
        CouponActivity.actionStart(mActivity);
    }

    @Override
    public BridgeWebView getWebView() {
        return mWebView;
    }

    @Override
    public void notifyDataChanged() {
        mPresenter.tellJsLoginStateChanged();
    }

    private void initWebViewSettings() {
        //获取关于网页的设置
        WebSettings mSettings = mWebView.getSettings();
        //当是查看配货单时支持缩放
        mSettings.setSupportZoom(mPresenter.isFreeScreenOrientation());
        // 加上这个属性后。。。html的图片就会以单列显示就不会变形占了别的位置
        mSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        // 让缩放显示的最小值为起始
        mWebView.setInitialScale(5);
        // 设置缩放工具的显示
        mSettings.setBuiltInZoomControls(true);
        // 设置支持缩放
        //不显示webView缩放按钮
        mSettings.setDisplayZoomControls(false);
        //使javascript的设置有效,交互时必须设置
        mSettings.setJavaScriptEnabled(true);
        mSettings.setUseWideViewPort(true);
        mSettings.setLoadWithOverviewMode(true);
        mSettings.setDomStorageEnabled(true);
        mSettings.setDatabaseEnabled(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //使用https和http混合方式
            mSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

        mWebView.addJavascriptInterface(new JavaScriptInterface(), "local_obj");
        // 加载进度条
        mWebView.setWebChromeClient(new BusinessWebChromeClient());

        // 修改user-agent
        mSettings.setUserAgentString(mSettings.getUserAgentString() + " " + Common.USER_AGENT_HINT);

        //对于Android 3.0以上版本，Android系统开放了部分JS接口。
        // 因此在这个版本范围下，尽管客户端自身没有使用addJavascriptInterface方法
        // 黑客仍可以透过系统开放的JS接口实施恶意操作, 故移除一下接口
        mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
        mWebView.removeJavascriptInterface("accessibility");
        mWebView.removeJavascriptInterface("accessibilityTraversal");

        //加载数据成功，隐藏进度条
        mWebView.setWebViewClient(new BusinessWebViewClient(mWebView));
    }

    private class JavaScriptInterface {
        @JavascriptInterface
        public void getSource(String value) {
            if (value != null) {
                mImageUrlsFromHtml = StringUtils.getImageUrlsFromHtml(value);
            }
        }
    }

    @Override
    public List<String> getImagesUrlsFromHtml() {
        return mImageUrlsFromHtml;
    }

    /**
     * 判断WebView是否能返回上一级界面
     */
    public boolean canGoBack() {
        return mWebView.canGoBack();
    }

    /**
     * 返回上一级界面
     */
    public void goBack() {
        mWebView.goBack();
    }

    private void initListeners() {

        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (canGoBack()) {
                    goBack();
                } else {
                    onBackPress();
                }
            }
        });

        mIbtnShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UmengUtils.onEvent(mActivity, R.string.umeng_active_button_share);
                doClientShare(mPresenter.getShareData());
            }
        });

        mArticleOperatorLayout.setOnItemClickListener(new ArticleOperatorLayout.OnItemClickListener() {
            @Override
            public void onItemClick(int position, Article article) {
                switch (position) {
                    case ArticleOperatorLayout.POSITION.BACK:
                        mActivity.finish();
                        break;
                    case ArticleOperatorLayout.POSITION.COMMENT:
                        toArticleCommentActivity(article, false);
                        break;
                    case ArticleOperatorLayout.POSITION.LIKE:
                        mPresenter.likeArticle(article);
                        break;
                    case ArticleOperatorLayout.POSITION.SHARE:
                        shareArticle(article.getShareEntity());
                        break;
                    case ArticleOperatorLayout.POSITION.CONFIRM:
                        if (Article.Extra.Key.ENROLL.equals(article.getExtra().getButtonKey())) {
                            toEnrollActivity(article);
                        }else if(Article.Extra.Key.BUY_GOODS.equals(article.getExtra().getButtonKey())){
                            toGoodsDetailActivity(article.getExtra().getGoodsId());
                        }
                        break;
                    case COMMENT_NOW:
                        toArticleCommentActivity(article, true);
                        break;
                }
            }
        });
    }

    private void shareArticle(ShareEntity shareEntity) {
        LogUtils.d("Article Share --> " + shareEntity.toString());
        ShareDialog dialog = new ShareDialog(mActivity);
        dialog.setShareLinkData(shareEntity);
        dialog.show();
    }

    @Override
    public void toEnrollActivity(Article article) {
        EnrollActivity.actionStart(mActivity, article.getExtra());
    }

    @Override
    public void toArticleCommentActivity(Article article, boolean commentNow) {
        ArticleCommentActivity.actionStart(mActivity, article.getArticleId(), commentNow);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_url;
    }

    @Override
    public void setPresenter(UrlContract.Presenter presenter) {
        mPresenter = presenter;
    }

    @Override
    public String getPagerTag() {
        return TAG;
    }

    @Override
    public void showToast(String text) {
        UIUtils.showToast(text);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        mRootContainer.removeAllViews();
        if (mWebView != null) {
            mWebView.removeAllViews();
            mWebView.destroy();
            mWebView = null;
        }
    }

    public void onBackPress() {
        if (mPresenter.isOnlinePay() && mPresenter.isFirstIn()) {
            if (mPresenter.getOrderPayId() != null) {
                // 普通订单在线支付
                toPayResultActivity(mPresenter.getOrderPayId(), null);
            } else {
                // 报名订单在线支付--可能成功/失败(没有调交互)
                // 需要查询报名的状态
                mPresenter.checkEnrollOnlinePayState();
            }
        }
        finishActivity();
    }

    @Override
    public void toEnrollPayFailedActivity(String recId) {
        EnrollPayFailedActivity.actionStart(mActivity, recId);
    }

    @Override
    public void setRequestedOrientation(boolean isDelivery) {
        //当是查看配货单时横屏
        mActivity.setRequestedOrientation(isDelivery
                ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void toPayResultActivity(String orderPayId, String orderId) {
        OrderResultActivity.actionStart(mActivity, orderPayId, orderId);
    }

    @Override
    public void toGoodsDetailActivity(String goodsId) {
        GoodsDetailActivity.actionStart(mActivity, goodsId);
    }

    @Override
    public void toShopDetailActivity(String supplierId) {
        ShopDetailActivity.actionStart(mActivity, supplierId);
    }

    @Override
    public void toShoppingCartFragment() {
        MainActivity.actionStart(mActivity, ShoppingCartFragment.TAG);
    }

    @Override
    public void toLoginActivity() {
        LoginActivity.actionStart(mActivity);
    }

    @Override
    public void toBrandGoodsActivity(String brandName, String brandId, String supplierId) {
        BrandGoodsActivity.actionStart(mActivity, brandName, brandId, supplierId);
    }

    @Override
    public void doClientShare(ShareEntity shareEntity) {
        UmengUtils.onEvent(mActivity, R.string.umeng_active_page_share);
        ShareDialog shareDialog = new ShareDialog(mActivity);
        shareDialog.show();

        if (shareEntity != null) {
            shareDialog.setShareLinkDataWithCallBack(shareEntity, new ShareDialog.PlatformActionHelper() {
                @Override
                public void onComplete(Platform platform, int i, HashMap<String, Object> hashMap) {
                    // 通知服务器客户端分享成功
                    mPresenter.tellJsClientShareSuccess();
                }
            });
        } else {
            shareDialog.setShareLinkData(mPresenter.createUrlShareData());
        }
    }

    @Override
    public void setShareIconVisible(boolean visibility) {
        mIbtnShare.setVisibility(visibility ? View.VISIBLE : View.GONE);
    }

    @Override
    public void toConfirmOrderActivity() {
        UmengUtils.onEvent(mActivity, R.string.umeng_active_page_buy);
        ConfirmOrderActivity.actionStart(mActivity, false);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(RefreshEnrollResultStateEvent event) {
        // 用户报名成功
        mArticleOperatorLayout.cannotEnroll();
    }

    @Override
    public void finishActivity() {
        mActivity.finish();
    }

    @Override
    public String getTitle() {
        return mTvTitle.getText().toString().trim();
    }

    @Override
    public void setToolbarVisible(boolean visible) {
        mToolbar.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    @Override
    public void setArticleOperatorLayoutVisible(boolean visible) {
        mArticleOperatorLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    @Override
    public void setBottomLayoutData(Article article) {
        mArticleOperatorLayout.setData(article);
    }

    @Override
    public void notifyLikeCountChanged() {
        mArticleOperatorLayout.notifyDataSetChanged();
    }

    @Override
    public void toRedPacketActivity() {
        UmengUtils.onEvent(mActivity, R.string.umeng_check_raffle);
        RedPacketActivity.actionStart(mActivity);
    }

    @Override
    public void toSignHistoryActivity() {
        UmengUtils.onEvent(mActivity, R.string.umeng_raffle_histoty);
        SignHistoryActivity.actionStart(mActivity);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (uploadMessage != null) {
            uploadMessage.onReceiveValue(null);
            uploadMessage = null;
        }
    }

    /**
     * 打开选择图片的对话框
     */
    private void openImageChooserActivity() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, getString(R.string.choose_images)), FILE_CHOOSER_RESULT_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 注意，如果直接使用activity中的onActivityResult，requestCode就会有问题，不再是 FILE_CHOOSER_RESULT_CODE
        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) {
                return;
            }
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
        if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null) {
            return;
        }
        Uri[] results = null;
        if (resultCode == RESULT_OK) {
            if (intent != null) {
                String dataString = intent.getDataString();
                ClipData clipData = intent.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }
        uploadMessageAboveL.onReceiveValue(results);
        uploadMessageAboveL = null;
    }

    private class BusinessWebViewClient extends BridgeWebViewClient {

        BusinessWebViewClient(BridgeWebView webView) {
            super(webView);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            //handler.cancel(); // Android默认的处理方式
            handler.proceed(); // 接受所有网站的证书
            //handleMessage(Message msg); // 进行其他处理
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            view.loadUrl("javascript:window.local_obj.getSource('<head>'+"
                    + "document.getElementsByTagName('html')[0].innerHTML+'</head>');");
        }
    }

    private class BusinessWebChromeClient extends android.webkit.WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                mPbProgress.setVisibility(View.GONE);
            } else {
                if (mPbProgress.getVisibility() == View.GONE) {
                    mPbProgress.setVisibility(View.VISIBLE);
                }
                mPbProgress.setProgress(newProgress);
            }

            BuglyUtils.setJavascriptMonitor(view);
            super.onProgressChanged(view, newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            mTvTitle.setText(title);
            setShareIconVisible(mPresenter.shareFeatureEnable());
        }

        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> valueCallback) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android  >= 3.0
        public void openFileChooser(ValueCallback valueCallback, String acceptType) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        //For Android  >= 4.1
        public void openFileChooser(
                ValueCallback<Uri> valueCallback, String acceptType, String capture) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
                                         WebChromeClient.FileChooserParams fileChooserParams) {
            uploadMessageAboveL = filePathCallback;
            openImageChooserActivity();
            return true;
        }
    }
}
